package com.wm.wmim.common.dto;

import com.wm.wmim.common.constant.RpcCommonConstant;
import lombok.Builder;

import java.io.Serializable;

/**
 * @author weiming
 * @date 2024/8/27 21:23
 * @description
 */
public class RpcRespDTO<T> implements Serializable {
    private static final long serialVersionUID = 7666778243265202736L;

    /**
     * 响应代码
     */
    private String code;
    /**
     * 响应消息 异常时呈现用户
     */
    private String msg;
    /**
     * 明细信息 仅作为开发调试使用
     */
    private String detail;
    /**
     * 响应数据
     */
    private T data;

    /**
     * 获取HTTP状态码，该业务状态码在此种HTTP状态码下会返回
     *
     * @return Integer 状态码，参考 org.springframework.http.HttpStatus 中的定义
     */
    private Integer httpStatus;

    /**
     * 额外携带的异常信息
     */
    private String exceptionExt;


    public RpcRespDTO() {

    }

    public RpcRespDTO(String code) {
        this(code, "", null);
    }

    public RpcRespDTO(String code, String msg) {
        this(code, msg, null);
    }

    public RpcRespDTO(String code, T data) {
        this(code, "", data);
    }


    public RpcRespDTO(String code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    @Builder
    public RpcRespDTO(String code, String msg, String detail, T data) {
        this.code = code;
        this.msg = msg;
        this.detail = detail;
        this.data = data;
    }

    public RpcRespDTO(String code, String msg, String detail, T data, Integer httpStatus) {
        this.code = code;
        this.msg = msg;
        this.detail = detail;
        this.data = data;
        this.httpStatus = httpStatus;
    }

    public String getDetail() {
        return detail;
    }

    public void setDetail(String detail) {
        this.detail = detail;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public Integer getHttpStatus() {
        return httpStatus;
    }

    public void setHttpStatus(Integer httpStatus) {
        this.httpStatus = httpStatus;
    }

    public RpcRespDTO<T> buildSuccessResp(T data) {
        this.code = RpcCommonConstant.CODE_SUCCESS;
        this.msg = RpcCommonConstant.MSG_SUCCESS;
        this.data = data;
        return this;
    }

    public RpcRespDTO<T> buildFailedResp(T data) {
        this.code = RpcCommonConstant.CODE_ERR_UNKNOW;
        this.msg = RpcCommonConstant.MSG_ERR_UNKNOW;
        this.detail = RpcCommonConstant.MSG_ERR_UNKNOW;
        this.data = data;
        return this;
    }

    public RpcRespDTO<T> buildFailedResp(String detail, T data) {
        this.code = RpcCommonConstant.CODE_ERR_UNKNOW;
        this.msg = RpcCommonConstant.MSG_ERR_UNKNOW;
        this.detail = detail;
        this.data = data;
        return this;
    }

    public RpcRespDTO<T> buildResourceNotFoundResp(String detail, T data) {
        this.code = RpcCommonConstant.CODE_ERR_RESOURCE_NOTFOUND;
        this.msg = RpcCommonConstant.MSG_ERR_RESOURCE_NOTFOUND;
        this.detail = detail;
        this.data = data;
        return this;
    }

    public RpcRespDTO<T> buildResp(String code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
        return this;
    }

    public RpcRespDTO<T> buildDetailResp(String code, String msg, String detail, T data) {
        this.code = code;
        this.msg = msg;
        this.detail = detail;
        this.data = data;
        return this;
    }

    /**
     * 构建rpc接口未实现的响应内容
     *
     * @return
     */
    public RpcRespDTO<T> buildNotImplResp() {
        this.code = RpcCommonConstant.CODE_ERR_METHOD_NOT_IMPLEMENT;
        this.msg = RpcCommonConstant.MSG_ERR_METHOD_NOT_IMPLEMENT;
        return this;
    }

    public RpcRespDTO<T> buildResp(String code, String msg) {
        return buildResp(code, msg, null);
    }

    public RpcRespDTO<T> buildResp(String code, String msg, String detail, Integer httpStatus) {
        this.code = code;
        this.msg = msg;
        this.detail = detail;
        this.httpStatus = httpStatus;
        return this;
    }

    public static <T> RpcRespDTO<T> buildSuccess(T data) {
        return RpcRespDTO.<T>builder()
                .code(RpcCommonConstant.CODE_SUCCESS)
                .msg(RpcCommonConstant.MSG_SUCCESS)
                .data(data)
                .build();
    }

    public static <T> RpcRespDTO<T> buildSuccess() {
        return RpcRespDTO.<T>builder()
                .code(RpcCommonConstant.CODE_SUCCESS)
                .msg(RpcCommonConstant.MSG_SUCCESS)
                .build();
    }

    public static <T> RpcRespDTO<T> buildUnknownErr() {
        return RpcRespDTO.<T>builder()
                .code(RpcCommonConstant.CODE_ERR_UNKNOW)
                .msg(RpcCommonConstant.MSG_ERR_UNKNOW)
                .build();
    }

    public static <T> RpcRespDTO<T> build(String code, String msg) {
        return RpcRespDTO.<T>builder()
                .code(code)
                .msg(msg)
                .build();
    }

    public static <T> RpcRespDTO<T> build(String code, String msg, String detail) {
        return RpcRespDTO.<T>builder()
                .code(code)
                .msg(msg)
                .detail(detail)
                .build();
    }

    /**
     * 构建rpc接口未实现的响应内容
     *
     * @return
     */
    public static <T> RpcRespDTO<T> buildNotImpl() {
        return RpcRespDTO.<T>builder()
                .code(RpcCommonConstant.CODE_ERR_METHOD_NOT_IMPLEMENT)
                .msg(RpcCommonConstant.MSG_ERR_METHOD_NOT_IMPLEMENT)
                .build();
    }

    /**
     * RPC 方法调用是否成功
     */
    public boolean isSuccess() {
        return RpcCommonConstant.CODE_SUCCESS.equals(code);
    }

    /**
     * RPC 方法调用是否失败
     */
    public boolean isFail() {
        return !RpcCommonConstant.CODE_SUCCESS.equals(code);
    }

    /**
     * RPC 方法调用是否为被熔断（针对RPC的服务熔断）
     */
    public boolean isBreaker() {
        return RpcCommonConstant.CODE_ERR_BREAKER.equals(code);
    }

    @Override
    public String toString() {
        return "RpcRespDTO{" +
                "code='" + code + '\'' +
                ", msg='" + msg + '\'' +
                ", detail='" + detail + '\'' +
                ", data=" + data +
                ", exceptionExt='" + exceptionExt + '\'' +
                '}';
    }

    public String getExceptionExt() {
        return exceptionExt;
    }

    public void setExceptionExt(String exceptionExt) {
        this.exceptionExt = exceptionExt;
    }
}
